package com.yc.biz;


import com.yc.bean.Account;
import com.yc.bean.OpRecord;
import com.yc.dao.AccountDao;
import com.yc.dao.OpRecordDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(rollbackFor = BizException.class)
//   Propagation propagation() default Propagation.REQUIRED;      传播机制
//      Isolation isolation() default Isolation.DEFAULT;         与数据库相同的隔离级别
//     int timeout() default -1;
//      boolean readOnly() default false;      表示默认为读写事务
public class AccountBizImpl implements AccountBiz{   //因为事务管理底层采用了aop机制，aop的动态代理优先  面向接口的jdk动态代理
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private OpRecordDao opRecordDao;




    @Override
    public Account deposite(int accountid, double money) throws BizException{
        //new UncategorizedSQLException(  );
        Account account=find( accountid);
        if(  account==null ){
            throw new RuntimeException("查无此"+ accountid+"用户 ");
        }


        OpRecord op=new OpRecord();
        op.setOpmoney(money);
        op.setAccountid(accountid);
        opRecordDao.insertOpRecord(op );

        account.setBalance(money);
        accountDao.updateAccount(    account   );

        account=find(accountid);


        return account;
    }

    @Override

    public Account withdraw(int accountid, double money) throws BizException{
        Account account=find( accountid);
        if(  account==null ){
            throw new BizException("查无此"+ accountid+"用户 ", "accountid");
        }
        //TODO:   正常要检查金额够不够,但这里为了测试check约束引起的事务回滚，故意没加

        money=-money;
        OpRecord op=new OpRecord();
        op.setOpmoney(money);
        op.setAccountid(accountid);
        opRecordDao.insertOpRecord(op );

        account.setBalance(money);
        try{
            accountDao.updateAccount(    account   ); // DataAccessException ==> RuntimeException
        } catch (DataAccessException e){
            throw new BizException("金额不足",e,"balance");
        }

        account=find(accountid);

        return account;
    }

    @Override
    public Account transfer(int outAccountId, int inAccountId, double money) throws BizException{
        deposite(  inAccountId, money );
        Account a= withdraw(   outAccountId,   money );
        return a;
    }

    @Override
    @Transactional( readOnly = true)
    public Account find(int accountid) {
        return accountDao.findAccount(accountid);
    }

    @Override
    public void register(Account account) throws BizException {
        if(accountDao.countByName(account.getName())>0){
            throw new BizException("用户名已经被注册", "name");
        }
        accountDao.insert(account);
        OpRecord op=new OpRecord();
        op.setOpmoney(account.getBalance());
        // 只有insert(account) 后, account 才有 accountid
        op.setAccountid(account.getAccountid());
        opRecordDao.insertOpRecord(op );
    }


}
